package com.yunchang.spring.visitor.core.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Dao基本方法的接口
 * Created by jasontujun on 2017/8/21.
 */
public interface IDao<T> {

    /**
     * 获取数据类型Class对象
     *
     * @return 返回数据类型Class对象
     */
    Class<T> getEntityClass();

    /**
     * 获取表名(@Table注解的name值)
     *
     * @return 返回表名
     */
    String getTableName();

    /**
     * 获取主键的属性名(@Id注解标识的属性名)
     *
     * @return 返回主键的属性名
     */
    String getIdFieldName();

    /**
     * 获取PO实例主键的值(@Id注解标识的属性的值)
     *
     * @param entity PO实例
     * @return 返回PO实例主键的值
     */
    String getIdFieldValue(T entity);

    /**
     * 获取PO的所有对象(慎用，考虑数据量是否过大)
     *
     * @return 返回表中所有数据
     */
    List<T> loadAll();

    /**
     * 通过主键延迟加载PO实例(适用于删除或建立关联关系的操作)
     *
     * @param id 主键的值
     * @return 如果找到，返回PO实例；如果找不到，则返回null
     */
    T load(Serializable id);

    /**
     * 通过主键获取PO实例
     *
     * @param id 主键的值
     * @return 如果找到，返回PO实例；如果找不到，则返回null
     */
    T get(Serializable id);

    /**
     * 通过主键数组获取多个PO实例(主键必须是唯一主键)
     *
     * @param ids 主键数组
     * @return 如果找到，返回PO实例列表；如果找不到，则返回空列表
     */
    List<T> getByIds(List<Serializable> ids);

    /**
     * 保存PO实例
     *
     * @param entity 数据
     */
    void save(T entity);

    /**
     * 更新PO实例
     *
     * @param entity 数据
     */
    void update(T entity);

    /**
     * 保存或更新PO实例
     *
     * @param entity 数据
     */
    void saveOrUpdate(T entity);

    /**
     * 保存多个PO实例
     *
     * @param entities 数据列表
     */
    void saveAll(List<T> entities);

    /**
     * 合并PO实例(创建或更新)
     *
     * @param entity 数据
     */
    void merge(T entity);

    /**
     * 删除PO实例
     *
     * @param entity 数据
     */
    void remove(T entity);

    /**
     * 删除多个PO实例
     *
     * @param entities 数据
     */
    void removeAll(List<T> entities);

    /**
     * 查询一个符合条件的PO实例。
     * 注意:该操作只是做多个paramName=paramValue的AND逻辑的查询
     *
     * @param paramsName  OP实例属性名
     * @param paramsValue OP实例属性对应的值
     * @return 返回一个符合条件的PO实例
     */
    T findOne(String[] paramsName, Object... paramsValue);

    /**
     * 查询所有符合条件的PO实例。
     * 注意:该操作只是做多个paramName=paramValue的AND逻辑的查询
     *
     * @param paramsName  OP实例属性名
     * @param paramsValue OP实例属性对应的值
     * @return 返回所有符合条件的PO实例
     */
    List<T> findAll(String[] paramsName, Object... paramsValue);

    /**
     * 查询所有符合条件的PO实例。
     *
     * @param properties  参数map  key为对应entity的属性名
     * @return 返回所有符合条件的PO实例
     */
    List<T> findAll(Map<String, String> properties);

    /**
     * 分页查询
     *
     * @param properties 查询条件
     * @param start      当前页第一个index
     * @param pageSize   页面大小
     * @param sortKey    排序key
     * @param isASC      是否升序
     * @return 返回所有符合条件的PO实例
     */
    List<T> findAllByPage(int start, int pageSize, String sortKey, boolean isASC, Map<String, String> properties);

}
